package com.rzico.sbl.ui.manager

import android.Manifest
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
import android.provider.Settings
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.core.view.isVisible
import com.amap.api.centerOfGravityPoint
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.fondesa.kpermissions.allGranted
import com.fondesa.kpermissions.anyPermanentlyDenied
import com.fondesa.kpermissions.extension.permissionsBuilder
import com.fondesa.kpermissions.extension.send
import com.jeremyliao.liveeventbus.LiveEventBus
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityMasterAreaBinding
import com.rzico.sbl.model.BaseUrl
import com.rzico.sbl.model.DrawLatLng
import com.rzico.sbl.model.DrawPolygon
import com.rzico.sbl.model.MasterData
import com.rzico.sbl.other.showBottomAreaDialog
import com.rzico.sbl.other.userRole
import com.rzico.sbl.viewmodel.MasterViewModel
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.intValue
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.utils.*
import org.json.JSONArray


class MasterAreaActivity : BaseActivity(R.layout.activity_master_area) {

    private val mBinding by lazy { ActivityMasterAreaBinding.bind(getRootView()) }

    override fun getViewModel() = get<MasterViewModel>()

    private lateinit var mLauncher: ActivityResultLauncher<Intent>

    private val mColors = arrayOf(
        Color.parseColor("#66FFD100"),
        Color.parseColor("#66A75FEA"),
        Color.parseColor("#6625D6FF"),
        Color.parseColor("#662486F8"),
        Color.parseColor("#66F75881"),
        Color.parseColor("#6600CFB5"),
        Color.parseColor("#66FF491F"),
    )

    // 员工列表
    private val mMemberList = arrayListOf<MasterData>()

    // 员工区域集合
    private val mPolygonList = arrayListOf<DrawPolygon>()

    private var mMemberId = ""
    private var mMemberIndex = -1
    private var mPolygonIndex = -1

    override fun initData() {
        initTitle(title = "区域配送")

        mLauncher = requestForResult { initAmap() }

        requestPermission()
    }

    /**
     * 定位权限申请
     */
    private fun requestPermission() {
        permissionsBuilder(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
            .build()
            .send {
                when {
                    it.allGranted() -> initAmap()
                    it.anyPermanentlyDenied() -> showPermissionDialog()
                    else -> finishView()
                }
            }
    }

    /**
     * 权限禁止显示后提示操作
     */
    private fun showPermissionDialog() {
        showHintDialog(
            title = "提示",
            hint = "位置权限被禁止开启，请打开权限设置页面手动开启",
            sure = "去设置",
            cancel = "再想想",
            isForced = true,
            onCancel = { finishView() },
            onSure = {
                mLauncher.launch(
                    Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        .apply {
                            data = Uri.parse("package:$packageName")
                        }
                )
            }
        )
    }

    /**
     * 地图显示初始化
     */
    private fun initAmap() {
        mBinding
            .areaMap
            .map
            .apply {
                uiSettings.apply {
                    isZoomControlsEnabled = false     //缩放按钮，默认打开
                    isCompassEnabled = false          //指南针，默认不显示
                    isMyLocationButtonEnabled = false //定位按钮
                    isScaleControlsEnabled = true     //比例尺
                    isScrollGesturesEnabled = true    //滑动手势
                    isZoomGesturesEnabled = true      //缩放手势
                    isRotateGesturesEnabled = false   //旋转手势
                    isTiltGesturesEnabled = false     //倾斜手势
                    setLogoBottomMargin(-100)         //隐藏logo
                }

                mapType = AMap.MAP_TYPE_NAVI   //导航地图模式
                isTrafficEnabled = false       //实时交通状况
                showBuildings(true)            //显示3D楼块
                showMapText(true)              //显示底图文字
                showIndoorMap(true)            //设置是否显示室内地图
                isMyLocationEnabled = true     //是否触发定位并显示定位层

                // 定位图层设置
                myLocationStyle = MyLocationStyle().apply {
                    // 定位一次，且将视角移动到地图中心点
                    myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE)
                    strokeColor(Color.TRANSPARENT)     //设置定位蓝点精度圆圈的边框颜色
                    radiusFillColor(Color.TRANSPARENT) //设置定位蓝点精度圆圈的填充颜色
                    showMyLocation(true)               //设置是否显示定位小蓝点
                    // 设置定位蓝点的icon图标方法
                    myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location_point))
                }

                // 自定义地图
                setCustomMapStyle(
                    CustomMapStyleOptions().apply {
                        isEnable = true
                        styleData = getByteFromAssets("style.data")
                        styleExtraData = getByteFromAssets("style_extra.data")
                    }
                )

                // 设置用户定位信息监听
                setOnMyLocationChangeListener { getMemberList() }

                // marker点击事件监听
                setOnMarkerClickListener { marker ->
                    (userRole in "1,2")
                        .condition {
                            val items = marker.snippet.split(",")

                            showBottomAreaDialog(
                                hint = items[2],
                                onSelect = {
                                    mPolygonIndex = items[0].intValue

                                    when (it) {
                                        0 -> showMemberDialog("change")
                                        1 ->
                                            startActivityEx<MasterAreaEditActivity>(
                                                "mode" to "edit",
                                                "areaId" to mPolygonList[mPolygonIndex].polygonId,
                                                "memberId" to mPolygonList[mPolygonIndex].memberId,
                                                "points" to mPolygonList[mPolygonIndex].point
                                            )
                                        2 ->
                                            showHintDialog(
                                                title = "删除区域",
                                                hint = "确定要删除该区域吗？",
                                                onSure = { deleteArea() }
                                            )
                                    }
                                }
                            )
                        }

                    true
                }

                // moveCamera(CameraUpdateFactory.changeTilt(60f)) //设置地图倾斜度，单位角度，范围（0,60）
                moveCamera(CameraUpdateFactory.zoomTo(14f)) //设置地图缩放级别
                moveCamera(CameraUpdateFactory.newLatLng(LatLng(34.7466, 113.625367))) //默认显示郑州经纬度
            }
    }

    override fun initListener() {
        mBinding.apply {
            areaBottom.isVisible = userRole in "1,2"

            areaNew
                .oneClick {
                    mMemberList
                        .notEmpty {
                            showMemberDialog("add")
                        }
                }
        }

        @Suppress("UNCHECKED_CAST")
        LiveEventBus
            .get("areaEdit", ArrayList::class.java)
            .observe(this) { items ->
                items as ArrayList<DrawLatLng>

                when {
                    mPolygonIndex < 0 -> {
                        mPolygonList.forEach {
                            it.marker?.remove()
                            it.polygon?.remove()
                        }

                        getMemberList()
                    }
                    else -> {
                        mPolygonList[mPolygonIndex].point = items

                        drawPolygon(mPolygonIndex)
                    }
                }
            }
    }

    /**
     * 员工列表弹框
     */
    private fun showMemberDialog(mode: String) {
        showListDialog(
            title = "请选择员工",
            items = mMemberList
                .map {
                    "${it.name.orEmpty()} ${it.mobile.orEmpty()}"
                },
            listener = { index, _ ->
                mMemberList[index]
                    .shopId
                    .orEmpty()
                    .isEmpty()
                    .condition {
                        showLongToast("该员工未设置所属店铺，暂无法操作")
                        return@showListDialog
                    }

                mMemberId = mMemberList[index].id

                when (mode) {
                    "add" -> {
                        mMemberIndex = -1
                        mPolygonIndex = -1

                        startActivityEx<MasterAreaEditActivity>(
                            "mode" to "add",
                            "memberId" to mMemberId
                        )
                    }
                    "change" -> {
                        mMemberIndex = index

                        changeAreaMember()
                    }
                }
            }
        )
    }

    /**
     * 删除员工区域
     */
    private fun deleteArea() {
        getViewModel()
            .requestBind(
                requestUrl = BaseUrl.mngAreaDel,
                params = arrayOf(
                    "id" to mPolygonList[mPolygonIndex].polygonId
                )
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    showToast("区域删除成功！")

                    mPolygonList[mPolygonIndex]
                        .apply {
                            polygon?.remove()
                            marker?.remove()
                        }
                }
            )
    }

    /**
     * 更换区域员工
     */
    private fun changeAreaMember() {
        getViewModel()
            .requestBind(
                requestUrl = BaseUrl.mngAreaChe,
                params = arrayOf(
                    "id" to mPolygonList[mPolygonIndex].polygonId,
                    "adminId" to mMemberId
                )
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    showToast("更换员工成功！")

                    mPolygonList[mPolygonIndex]
                        .apply {
                            memberId = mMemberId
                            memberName = mMemberList[mMemberIndex].name.orEmpty()
                        }

                    drawPolygon(mPolygonIndex)
                }
            )
    }

    /**
     * 员工列表
     */
    private fun getMemberList() {
        getViewModel()
            .masterShop(requestUrl = BaseUrl.mngList)
            .bindLifeCycle(getLifecycleOwner())
            .subscribeByFinally(
                event = getViewModel(),
                onSuccess = { list ->
                    mMemberList.clear()
                    mPolygonList.clear()

                    list.notEmpty {
                        mMemberList.addAll(
                            filter { it.roleId in "1,2,3,10" }
                        )
                    }

                    mMemberList
                        .filter { it.fences.isNotEmpty() }
                        .forEach { item ->
                            item.fences.forEach { data ->
                                val items = arrayListOf<DrawLatLng>()
                                val arr = JSONArray(data.points)

                                (0 until arr.length()).forEach {
                                    val obj = arr.getJSONObject(it)
                                    items.add(
                                        DrawLatLng(
                                            LatLng(
                                                obj.optDouble("lat"),
                                                obj.optDouble("lng")
                                            ),
                                            obj.optNotNull("big") == "1"
                                        )
                                    )
                                }

                                mPolygonList.add(
                                    DrawPolygon(
                                        memberId = item.id,
                                        polygonId = data.id,
                                        memberName = item.name.orEmpty(),
                                        point = items
                                    )
                                )
                            }
                        }

                    mPolygonList
                        .notEmpty {
                            forEachIndexed { index, _ ->
                                drawPolygon(index)
                            }
                        }
                }
            )
    }

    /**
     * 绘制多边形
     */
    private fun drawPolygon(index: Int) {
        val polygonItem = mPolygonList[index]

        polygonItem.marker?.remove()
        polygonItem.polygon?.remove()

        polygonItem.polygon =
            mBinding.areaMap.map.addPolygon(
                PolygonOptions()
                    .addAll(polygonItem.point.map { it.latLng })
                    .strokeWidth(2f)
                    .strokeColor(getColorEx(R.color.transparent))
                    .fillColor(mColors[index % mColors.size])
                    .zIndex(100f)
            )

        // 移动镜头到当前视角
        val bounds = LatLngBounds
            .Builder()
            .apply {
                mPolygonList.forEach { item ->
                    item.point.onEach { include(it.latLng) }
                }
            }
            .build()

        mBinding.areaMap.map
            .animateCamera(
                CameraUpdateFactory
                    .newLatLngBounds(bounds, 100)
            )

        drawMarker(index, polygonItem)
    }

    /**
     * 绘制区域重心点
     */
    private fun drawMarker(index: Int, item: DrawPolygon) {
        if (item.point.size > 5) {
            val centerPoint =
                item.point.map { it.latLng }.centerOfGravityPoint()

            item.marker =
                mBinding.areaMap.map.addMarker(
                    MarkerOptions()
                        .icon(
                            BitmapDescriptorFactory
                                .fromView(
                                    inflate<TextView>(R.layout.layout_marker_area_name)
                                        .apply { text = item.memberName }
                                )
                        )
                        .snippet("${index},${item.memberId},${item.memberName}")
                        .anchor(0.5f, 0.5f)
                        .position(centerPoint)
                )
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mBinding.areaMap.onCreate(savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState, outPersistentState)
        // onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mBinding.areaMap.onSaveInstanceState(outState)
    }

    override fun onResume() {
        super.onResume()
        // onResume时执行mMapView.onResume ()，重新绘制加载地图
        mBinding.areaMap.onResume()
    }

    override fun onPause() {
        super.onPause()
        // onPause时执行mMapView.onPause ()，暂停地图的绘制
        mBinding.areaMap.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        // onDestroy时执行mMapView.onDestroy()，销毁地图
        mBinding.areaMap.onDestroy()
    }

}